package py.com.alfa.escriba.web.services.impl;

import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DuplicateKeyException;

import java.util.Date;
import java.util.List;

import py.com.alfa.escriba.exception.ErrorCode;
import py.com.alfa.escriba.exception.ServiceException;
import py.com.alfa.escriba.persistence.dao.AdminDAO;
import py.com.alfa.escriba.persistence.dao.InmueblesDAO;
import py.com.alfa.escriba.persistence.dao.InmuebleslinderosDAO;
import py.com.alfa.escriba.persistence.dao.ReferenciaDAO;
import py.com.alfa.escriba.persistence.dto.InmueblesDTO;
import py.com.alfa.escriba.persistence.dto.InmuebleslinderosDTO;
import py.com.alfa.escriba.util.ObjectUtils;
import py.com.alfa.escriba.util.Utils;
import py.com.alfa.escriba.web.interceptor.InvocationContext;
import py.com.alfa.escriba.web.services.InmueblesService;

public class InmueblesServiceImpl implements InmueblesService{

  private InmueblesDAO inmueblesDAO;
  private InmuebleslinderosDAO inmuebleslinderosDAO;
  private AdminDAO adminDAO;
  private ReferenciaDAO referenciaDAO;

  public void setReferenciaDAO(ReferenciaDAO referenciaDAO) {
		this.referenciaDAO = referenciaDAO;
  }
  public void setAdminDAO(AdminDAO adminDAO) {
	this.adminDAO = adminDAO;
  }
  public void setInmueblesDAO(InmueblesDAO inmueblesDAO) {
    this.inmueblesDAO = inmueblesDAO;
  }
  public void setInmuebleslinderosDAO(InmuebleslinderosDAO inmuebleslinderosDAO) {
		this.inmuebleslinderosDAO = inmuebleslinderosDAO;
  }
  
  @Override
  public List<InmueblesDTO> listInmuebles(InvocationContext ic) throws ServiceException {
    List<InmueblesDTO> inmuebless =  inmueblesDAO.listInmuebles();

    return inmuebless;
  }

  @Override
  public InmueblesDTO getInmuebles(Long id, InvocationContext ic) throws ServiceException {
    if (id == null || id <= 0)
      throw new ServiceException(ErrorCode.PARAMETER_ERROR,"parameter.error.null","id");

    InmueblesDTO inmuebles =  inmueblesDAO.getInmueblesById(id);

    if (inmuebles == null)
      throw new ServiceException(ErrorCode.NO_DATA_FOUND,"inmuebles.notfound", id);
	inmuebles.setUm(adminDAO.getTabRefsById(inmuebles.getIdunidadmedida()));
	inmuebles.setDistrito(referenciaDAO.getDistritoById(inmuebles.getIddistrito()));
	inmuebles.setLinderosList(getLinderosByIdInmueble(inmuebles.getId()));

    return inmuebles;
  }

  private List<InmuebleslinderosDTO> getLinderosByIdInmueble(Long id) {
	List<InmuebleslinderosDTO> linderos = inmuebleslinderosDAO.getInmuebleslinderosByIdInmueble(id);
	if(linderos!= null ){
		for(InmuebleslinderosDTO il:linderos){
			il.setUm(adminDAO.getTabRefsById(il.getIdunidadmedida()));
		}
	}
	return linderos;
}
@Override
  public void deleteInmuebles(Long id, InvocationContext ic) throws ServiceException {
    if (id == null || id <= 0)
      throw new ServiceException(ErrorCode.PARAMETER_ERROR,"parameter.error.null","id");

    InmueblesDTO inmuebles =  inmueblesDAO.getInmueblesById(id);

    if(inmuebles == null)
      throw new ServiceException(ErrorCode.NO_DATA_FOUND,"inmuebles.notfound", id);

    try {
      inmuebleslinderosDAO.deleteInmuebleslinderosByIdInmueble(id);
      inmueblesDAO.deleteInmuebles(inmuebles);
    }
    catch (DataIntegrityViolationException e){
      throw new ServiceException(ErrorCode.DATA_INTEGRITY_VIOLATION, "inmuebles.constraint.violation", id);
    }

  }

  @Override
  public InmueblesDTO updateInmuebles(Long id, InmueblesDTO dto, InvocationContext ic) throws ServiceException {
    if (id == null || id <= 0)
      throw new ServiceException(ErrorCode.PARAMETER_ERROR,"parameter.error.null","id");

    if (null == dto)
      throw new ServiceException(ErrorCode.PARAMETER_ERROR,"parameter.error.null","dto");

    InmueblesDTO inmuebles = inmueblesDAO.getInmueblesById(id);

    if (inmuebles == null)
      throw new ServiceException(ErrorCode.NO_DATA_FOUND,"inmuebles.notfound", id);

    dto.setIdescribano(ic.getIdEscribano());
    dto.setIdusuariomodificacion(ic.getIdUserPrincipal());
    dto.setFechamodificacion(new Date(System.currentTimeMillis()));

    Utils.validarDTO(dto);

    inmueblesDAO.updateInmuebles(dto);
    inmuebleslinderosDAO.deleteInmuebleslinderosByIdInmueble(dto.getId());
    Long orden=1L;
    for (InmuebleslinderosDTO l: dto.getLinderosList()){
  	  l.setIdinmueble(dto.getId());
  	  l.setOrden(orden);
  	  orden++;
  	  inmuebleslinderosDAO.createInmuebleslinderos(l);
    }
    return inmuebles;
  }

  @Override
  public InmueblesDTO createInmuebles(InmueblesDTO dto, InvocationContext ic) throws ServiceException {
    if (dto == null)
      throw new ServiceException(ErrorCode.PARAMETER_ERROR,"parameter.error.null","dto");
    if (ic.getIdEscribano() == null)
        throw new ServiceException(ErrorCode.PARAMETER_ERROR,"parameter.error.null","escribano");

    try {

      Utils.validarDTO(dto);
//      Long trn = inmueblesDAO.get
//      dto.setTrn(trn+1L);
      dto.setIdescribano(ic.getIdEscribano());
      dto.setIdusuario(ic.getIdUserPrincipal());
      dto.setFechacreacion(new Date(System.currentTimeMillis()));

      inmueblesDAO.createInmuebles(dto);
      Long orden=1L;
      for (InmuebleslinderosDTO l: dto.getLinderosList()){
    	  l.setIdinmueble(dto.getId());
    	  l.setOrden(orden);
    	  orden++;
    	  inmuebleslinderosDAO.createInmuebleslinderos(l);
      }
      
    }
    catch (DuplicateKeyException e){
      throw new ServiceException(ErrorCode.DUPLICATE_KEY_EXCEPTION, "inmuebles.duplicate.key");
    }

    return dto;
  }

  @Override
  public List<InmueblesDTO> buscarInmuebles(InmueblesDTO dto, InvocationContext ic) throws ServiceException {
	  if (null == dto)
		  throw new ServiceException(ErrorCode.PARAMETER_ERROR,"parameter.error.null","dto");
	  if (ic.getIdEscribano() != null)
		  dto.setIdescribano(ic.getIdEscribano());
	  
	  String like = "%%%s%%";
	  if(ObjectUtils.isNotEmpty(dto.getFinca())){
		  dto.setFinca(String.format(like, dto.getFinca()));
	  }
	  if(ObjectUtils.isNotEmpty(dto.getMatricula())){
		  dto.setMatricula(String.format(like, dto.getFinca()));
	  }
	  if(ObjectUtils.isNotEmpty(dto.getCuentacorriente())){
		  dto.setCuentacorriente(String.format(like, dto.getCuentacorriente()));
	  }
	  List<InmueblesDTO> inmuebles =  inmueblesDAO.buscarInmuebles(dto);
	  if(inmuebles!=null){
		  for(InmueblesDTO i:inmuebles){
			  i.setUm(adminDAO.getTabRefsById(i.getIdunidadmedida()));
			  i.setDistrito(referenciaDAO.getDistritoById(i.getIddistrito()));
		  }
	  }
	  return inmuebles;

  }

}